package com.chenxin.interact.process.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chenxin.common.constant.WmsConstants;
import com.chenxin.common.core.domain.ProcResult;
import com.chenxin.common.enums.wms.IbMasterType;
import com.chenxin.common.exception.ServiceException;
import com.chenxin.common.utils.ConvertUtils;
import com.chenxin.common.utils.StringUtils;
import com.chenxin.interact.domain.dto.SapPurchaseReqDTO;
import com.chenxin.interact.domain.dto.SapQualityResultDTO;
import com.chenxin.interact.domain.dto.SrmBarcodeReqDTO;
import com.chenxin.interact.domain.dto.SrmDeliverReqDTO;
import com.chenxin.interact.domain.sapDetail.*;
import com.chenxin.interact.domain.sapToWms.SapToWmsPoDt;
import com.chenxin.interact.domain.sapToWms.SapToWmsPoMt;
import com.chenxin.interact.domain.sapToWms.SapToWmsQuality;
import com.chenxin.interact.domain.srmToWms.SrmToWmsBarcode;
import com.chenxin.interact.domain.srmToWms.SrmToWmsDeliverDt;
import com.chenxin.interact.domain.srmToWms.SrmToWmsDeliverMt;
import com.chenxin.interact.mapper.*;
import com.chenxin.interact.process.ISapInteractProcess;
import com.chenxin.wms.domain.DeliverDetailEntity;
import com.chenxin.wms.domain.DeliverMasterEntity;
import com.chenxin.wms.domain.IbDetailEntity;
import com.chenxin.wms.domain.IbMasterEntity;
import com.chenxin.wms.mapper.DeliverDetailMapper;
import com.chenxin.wms.mapper.DeliverMasterMapper;
import com.chenxin.wms.mapper.IbDetailMapper;
import com.chenxin.wms.mapper.IbMasterMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SapInteractProcessImpl implements ISapInteractProcess {

    @Autowired
    private SapToWmsPoMtMapper poMtMapper;
    @Autowired
    private SapToWmsPoDtMapper PoDtMapper;
    @Autowired
    private IbMasterMapper ibMasterMapper;
    @Autowired
    private IbDetailMapper ibDetailMapper;
    @Autowired
    private SrmToWmsDeliverDtMapper deliverDtMapper;
    @Autowired
    private SrmToWmsDeliverMtMapper deliverMtMapper;
    @Autowired
    private DeliverMasterMapper deliverMasterMapper;
    @Autowired
    private DeliverDetailMapper deliverDetailMapper;
    @Autowired
    private SrmToWmsBarcodeMapper barcodeMapper;
    @Autowired
    private SapToWmsQualityMapper qualityMapper;

    /**
     * 采购订单处理
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ProcResult procSapPurchase(SapPurchaseReqDTO dto) {
        // 参数校验
        if (dto == null || dto.getHead() == null) {
            return ProcResult.error("order_err#001", "请求参数不能为空");
        }
        if (dto.getItem1() == null) {
            return ProcResult.error("order_err#002", "订单明细【IT_ITEM1】不能为空");
        }
        // 主单内容包括（采购订单编号、订单类型、供应商信息、采购订单创建日期）
        SapIsReq isReq = dto.getIsReq();
        String reqKeyId = isReq.getReqKeyId();
        Date workDate = new Date();
        // 获取主单HEAD内容
        List<SapPoHead> masters = dto.getHead().getHeadItems();

        // 获取明细ITEM内容
        List<SapPoItem1> details = dto.getItem1().getItem1s();

        // 明细的domain
        List<SapToWmsPoDt> dtList = new ArrayList<>(details.size());
        ArrayList<IbDetailEntity> detailList = new ArrayList<>();

        // 循环处理主单与明细
        for (SapPoHead master : masters) {
            String ebeln = master.getEbeln();
            // 判断采购订单是否已存在
            QueryWrapper<SapToWmsPoMt> existQW = new QueryWrapper<>();
            existQW.lambda().eq(SapToWmsPoMt::getEbeln, ebeln)
                    .lt(SapToWmsPoMt::getStatus, 4)
                    .last("limit 1");
            SapToWmsPoMt existPo = poMtMapper.selectOne(existQW);
            // TODO 对于已存在的单据判断是否为UPDATE或DELETE
            if (existPo != null) {
                throw new ServiceException("采购订单【" + ebeln + "】已存在！不允许重复下发");
            }
            // 判断采购订单是否已生成入库单据
            QueryWrapper<IbMasterEntity> ibQW = new QueryWrapper<>();
            ibQW.lambda().eq(IbMasterEntity::getEbeln, ebeln).lt(IbMasterEntity::getIbMasterStatus, 4).last("limit 1");
            IbMasterEntity ibMaster = ibMasterMapper.selectOne(ibQW);
            if (ibMaster != null) {
                throw new ServiceException("采购订单【" + ebeln + "】已生成入库单【" + ibMaster.getIbMasterNo() + "】，不允许重复下发");
            }
            // 构建接口主单
            SapToWmsPoMt wmsPo = ConvertUtils.sourceToTarget(master, SapToWmsPoMt.class);
            wmsPo.setReqKeyId(reqKeyId);
            wmsPo.setCreator(100L);
            wmsPo.setCreateDate(workDate);
            // 写入接口主单
            poMtMapper.insert(wmsPo);
            // 构建入库主单
            IbMasterEntity insertMaster = new IbMasterEntity();
            // 生成主单号（规则为I-EBELN）
            String ibMasterNo = WmsConstants.IB_NO_PREFIX + ebeln;
            insertMaster.setIbMasterNo(ibMasterNo);
            insertMaster.setIbMasterType(IbMasterType.IN_WIP.getCode());
            insertMaster.setFromErp("1");
            insertMaster.setEbeln(ebeln);
            insertMaster.setAedat(master.getAedat());
            insertMaster.setSupplierNo(master.getLifnr());
            // TODO 根据物料信息获取对应仓库
            insertMaster.setWarehouseId(300L);
            insertMaster.setCreator(100L);
            insertMaster.setCreateDate(workDate);

            // 写入入库主单
            ibMasterMapper.insert(insertMaster);

            // 处理同一订单下的明细信息
            details.stream().filter(detail -> StringUtils.equals(detail.getEbeln(), ebeln))
                    .forEach(detail -> {
                        SapToWmsPoDt wmsDt = ConvertUtils.sourceToTarget(detail, SapToWmsPoDt.class);
                        wmsDt.setCreator(100L);
                        wmsDt.setCreateDate(workDate);
                        dtList.add(wmsDt);
                        // 入库明细
                        IbDetailEntity ibDetail = new IbDetailEntity();
                        ibDetail.setIbMasterId(insertMaster.getIbMasterId());
                        ibDetail.setIbMasterNo(ibMasterNo);
                        ibDetail.setEbeln(ebeln);
                        ibDetail.setEbelp(detail.getEbelp());
                        ibDetail.setSpuNo(detail.getMatnr());
                        ibDetail.setIbPlanQty(detail.getMenge());
                        ibDetail.setCreator(100L);
                        ibDetail.setCreateDate(workDate);
                        detailList.add(ibDetail);
                    });
        }
        // 将数据批量写入数据库
        PoDtMapper.insert(dtList);
        ibDetailMapper.insert(detailList);
        return ProcResult.success("采购订单接收成功!");
    }

    @Override
    public ProcResult procSrmDeliver(SrmDeliverReqDTO srmDeliverReqDTO) {
        if (srmDeliverReqDTO == null) {
            return ProcResult.error("order_err#001", "请求参数不能为空");
        }
        //获取头部LIST
        List<SrmDeliverHead> heads = srmDeliverReqDTO.getHead().getHeadItems();

        if (heads == null || heads.size() == 0) {
            return ProcResult.error("order_err#002", "请求头部【HEAD】不能为空");
        }
        //获取明细LIST
        List<SrmDeliverItem> details = srmDeliverReqDTO.getItem().getItems();

        if (details == null || details.size() == 0) {
            return ProcResult.error("order_err#003", "请求明细【ITEM】不能为空");
        }

        // 获取reqKeyId
        SapIsReq isReq = srmDeliverReqDTO.getIsReq();
        String reqKeyId = isReq.getReqKeyId();
        Date workDate = new Date();

        // 明细信息
        ArrayList<SrmToWmsDeliverDt> dtList = new ArrayList<>();

        ArrayList<DeliverDetailEntity> detailList = new ArrayList<>();

        //送货单头部是个List，批量插入接口表
        for (SrmDeliverHead master : heads) {
            // 判断送货单在接口中是否已存在
            String rcvNo = master.getRcvNo();
            QueryWrapper<SrmToWmsDeliverMt> existRcvNoQW = new QueryWrapper<>();
            existRcvNoQW.lambda().eq(SrmToWmsDeliverMt::getRcvNo, rcvNo)
                    .lt(SrmToWmsDeliverMt::getStatus, 4)
                    .last("limit 1");
            SrmToWmsDeliverMt existRcvNo = deliverMtMapper.selectOne(existRcvNoQW);
            if (existRcvNo != null) {
                throw new ServiceException("送货单【" + rcvNo + "】已存在！不允许重复下发");
            }
            // 判断送货单是否已经生成
            QueryWrapper<DeliverMasterEntity> existMasterQW = new QueryWrapper<>();
            existMasterQW.lambda().eq(DeliverMasterEntity::getRcvNo, rcvNo)
                    .lt(DeliverMasterEntity::getStatus, 4)
                    .last("limit 1");
            DeliverMasterEntity existMaster = deliverMasterMapper.selectOne(existMasterQW);
            if (existMaster != null) {
                throw new ServiceException("送货单【" + rcvNo + "】已生成单据，不允许重复下发");
            }
            // 需要判断采购订单是否已经生成
            // 写入接口表
            SrmToWmsDeliverMt deliverMt = ConvertUtils.sourceToTarget(master, SrmToWmsDeliverMt.class);
            deliverMt.setReqKeyId(reqKeyId);
            deliverMt.setCreator(100L);
            deliverMt.setCreateDate(workDate);
            deliverMtMapper.insert(deliverMt);
            // 写入送货单表
            DeliverMasterEntity deliverMaster = new DeliverMasterEntity();
            deliverMaster.setRcvNo(rcvNo);
            deliverMaster.setVCode(master.getVCode());
            deliverMaster.setVName(master.getVName());
            deliverMaster.setBuyer(master.getBuyer());
            deliverMaster.setDeliveryTime(master.getDeliveryTime());
            deliverMaster.setDeliveryTimeHh(master.getDeliveryTimeHh());
            deliverMaster.setReceivingAddress(master.getReceivingAddress());
            deliverMaster.setDeliveryMan(master.getDeliveryMan());
            deliverMaster.setContractNo(master.getContractNo());
            deliverMaster.setCreator(100L);
            deliverMaster.setCreateDate(workDate);
            deliverMasterMapper.insert(deliverMaster);
            // 处理明细信息
            details.stream().filter(detail -> StringUtils.equals(detail.getRcvNo(), rcvNo))
                    .forEach(detail -> {
                        // TODO 判断采购订单是否已下发
                        SrmToWmsDeliverDt deliverDt = ConvertUtils.sourceToTarget(detail, SrmToWmsDeliverDt.class);
                        deliverDt.setCreator(100L);
                        deliverDt.setCreateDate(workDate);
                        dtList.add(deliverDt);
                        // 同时生成送货单明细
                        DeliverDetailEntity deliverDetail = new DeliverDetailEntity();
                        deliverDetail.setRcvNo(rcvNo);
                        deliverDetail.setPoNo(detail.getPoNo());
                        deliverDetail.setPoLine(detail.getPoLine());
                        deliverDetail.setSpuNo(detail.getPartNo());
                        deliverDetail.setNeedTime(detail.getNeedTime());
                        deliverDetail.setPoQty(detail.getPoQty());
                        deliverDetail.setRcvdQty(detail.getRcvdQty());
                        deliverDetail.setShpQty(detail.getShpQty());
                        deliverDetail.setSupplierNo(detail.getVendorCode());
                        deliverDetail.setCreator(100L);
                        deliverDetail.setCreateDate(workDate);
                        detailList.add(deliverDetail);
                    });
        }
        if (dtList.size() > 0) {
            deliverDtMapper.insert(dtList);
        }
        if (detailList.size() > 0) {
            deliverDetailMapper.insert(detailList);
        }
        // 将主明细信息写入数据库
        return ProcResult.success("送货单接收成功!");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ProcResult procSrmBarcode(SrmBarcodeReqDTO barcodeDto) {
        if (barcodeDto == null) {
            return ProcResult.error("order_err#001", "请求参数不能为空");
        }
        // 获取头部LIST
        SapIsReq isReq = barcodeDto.getIsReq();
        // 获取reqKeyId
        String reqKeyId = isReq.getReqKeyId();
        Date workDate = new Date();

        // 获取条码信息
        SrmBarcodeReqDTO.Head head = barcodeDto.getHead();
        if (head == null) {
            return ProcResult.error("order_err#002", "请求头【HEAD】不能为空");
        }
        List<SrmBarcodeData> items = head.getDataItems();
        if (items == null || items.size() == 0) {
            return ProcResult.error("order_err#003", "条码信息不能为空");
        }

        ArrayList<SrmToWmsBarcode> wmsBarcodes = new ArrayList<>();
        for (SrmBarcodeData item : items) {
            // 条码信息不能重复传输
            String barcodeNo = item.getBarcodeNo();
            QueryWrapper<SrmToWmsBarcode> existBarcodeQW = new QueryWrapper<>();
            existBarcodeQW.lambda().eq(SrmToWmsBarcode::getBarcodeNo, barcodeNo);
            SrmToWmsBarcode existBarcode = barcodeMapper.selectOne(existBarcodeQW);
            if (existBarcode != null) {
                throw new ServiceException("条码【" + barcodeNo + "】已存在！不允许重复下发");
            }
            SrmToWmsBarcode barcode = ConvertUtils.sourceToTarget(item, SrmToWmsBarcode.class);
            barcode.setReqKeyId(reqKeyId);
            barcode.setCreator(100L);
            barcode.setCreateDate(workDate);
            wmsBarcodes.add(barcode);
        }
        barcodeMapper.insert(wmsBarcodes);
        return ProcResult.success("成功获取条码信息");
    }

    @Override
    public ProcResult procSapQuality(SapQualityResultDTO qualityResultDTO) {
        if (qualityResultDTO == null) {
            return ProcResult.error("order_err#001", "请求参数不能为空");
        }
        SapIsReq isReq = qualityResultDTO.getIsReq();
        String reqKeyId = isReq.getReqKeyId();
        Date workDate = new Date();
        SapQualityResultDTO.Head head = qualityResultDTO.getHead();
        if (head == null) {
            return ProcResult.error("order_err#002", "请求头【HEAD】不能为空");
        }
        // 获取对应采购订单的质检结果
        SrmQualityHead ebelnInfo = head.getDataItems().get(0);
        if (ebelnInfo == null || StringUtils.isEmpty(ebelnInfo.getEbeln())) {
            return ProcResult.error("order_err#003", "采购订单【EBELN】不能为空");
        }
        // 获取质检结果的明细
        List<SapQualityItem1> item1s = qualityResultDTO.getItem1().getItem1s();
        if (item1s == null || item1s.size() == 0) {
            return ProcResult.error("order_err#004", "质检结果【ITEM1】不能为空");
        }
        String ebeln = ebelnInfo.getEbeln();
        // 提取采购订单信息
        List<SapQualityItem2> item2s = qualityResultDTO.getItem2().getItem2s();
        // 根据采购订单获取对应单据
        QueryWrapper<IbMasterEntity> masterQW = new QueryWrapper<>();
        masterQW.lambda().eq(IbMasterEntity::getEbeln, ebeln);
        IbMasterEntity masterByQA = ibMasterMapper.selectOne(masterQW);
        if (masterByQA == null) {
            return ProcResult.error("order_err#005", "系统中不存在已收货的采购订单【" + ebeln + "】");
        }
        // 构建质检结果
        ArrayList<SapToWmsQuality> qaList = new ArrayList<>();
        for (SapQualityItem1 item1 : item1s) {
            // 获取质检批与物料信息
            String prueflos = item1.getPrueflos();
            String matnr = item1.getMatnr();
            SapToWmsQuality qa = ConvertUtils.sourceToTarget(item1, SapToWmsQuality.class);
            // 将公司集团、采购单号信息写入
            qa.setReqKeyId(reqKeyId);
            qa.setMandt(ebelnInfo.getMandt());
            qa.setBukrs(ebelnInfo.getBukrs());
            qa.setEbeln(ebeln);
            qa.setCreator(100L);
            qa.setCreateDate(workDate);
            // TODO 将合格的质检结果更新到库存表中
            // 根据质检批+物料号在item2s中获取对应信息
            item2s.stream()
                    .filter(item2 -> item2.getPrueflos().equals(prueflos) && item2.getMatnr().equals(matnr))
                    .findFirst()
                    .ifPresent(item2 -> {
                        qa.setAnzfehleh(item2.getAnzfehleh());
                        qa.setPruefer(item2.getPruefer());
                        qa.setVdatum(item2.getVdatum());
                    });
            qaList.add(qa);
        }
        qualityMapper.insert(qaList);
        return ProcResult.success("质检结果保存成功");
    }
}
